#include<iostream>
//#include<sys/select.h>
#include<poll.h>
#include"sock.hpp"
#include<string>
using namespace std;
//#define NUM (sizeof(fd_set)*8)
#define NUM 128
struct pollfd fd_array[NUM];
int num =NUM;
static void Usage(string proc)
{
  cout<<"Usage: "<<proc<<" port"<<endl;
}

int main(int argc,char* argv[])
{
  if(argc!=2)
  {
    Usage(argv[0]);
    exit(1);
  }
  uint16_t port = (uint16_t)atoi(argv[1]);
  int listen_sock = Sock::Socket(); 
  Sock::Bind(listen_sock,port);
  Sock::Listen(listen_sock);
  //memset(fd_array,-1,sizeof(fd_array));
  for(int i=0;i<(num);i++)//初始化
  {
    fd_array[i].fd=-1;
    fd_array[i].events=0;
    fd_array[i].revents = 0;
  }

 // fd_array[0] = listen_sock;
 // fd_set rfds;
  for(;;)
  {

  //  FD_ZERO(&rfds);//全部置0
  //  int max_fd = fd_array[0];

  //  for(int i=0;i<num;i++)
  //  {
  //    if(fd_array[i]==-1) continue;
  //    FD_SET(fd_array[i],&rfds);//把关心的读事件fd，添加到rfds
  //    if(max_fd<fd_array[i])
  //    {
  //      max_fd = fd_array[i];//更新最大fd
  //    }
  //  }
    fd_array[0].fd = listen_sock;
    fd_array[0].events = POLLIN;
    fd_array[0].revents = 0;
 //   struct timeval timeout = {5,0}; //5s
    //服务器上的所有fd（包括listen_sock）,都要交给select进行检测！
    //recv，read，write，send，accept：只需要负责自己最核心的工作，真正的读写 
    //int n = select(max_fd+1,&rfds,nullptr,nullptr,nullptr);
    int n =poll(fd_array, num,1000);
    switch(n)
    {
      case -1:
        cerr<<"select error"<<endl;
        break;
      case 0://超时间
        cout<<"select timeout"<<endl;
        break;
      default://大于0，代表有fd就绪了
        cout<<"有fd对应的事件就绪啦！"<<endl;
        for(int i =0;i<num;i++)
        {
          if(fd_array[i]==-1) continue;
          if(FD_ISSET(fd_array[i],&rfds))
          {
            //读事件就绪了
            //read,recv 一定不会被阻塞
            cout<<"listen_sock: "<<fd_array[i]<<" 上面有了读事件，可以读取了"<<endl;
            if(fd_array[i]==listen_sock)
            {
              //accept
              cout<<"listen_sock: "<<listen_sock<<" 有了新的链接到来"<<endl;
              int sock = Sock::Accept(listen_sock);                 
              if(sock>=0)
              {
                //获取成功
                cout<<"listen_sock: "<<listen_sock<<" 获取新连接成功"<<endl;
                int pos = 1;
                for(pos = 1;pos<num;pos++)
                {
                  if(fd_array[pos]==-1) break;
                }
                //1.找到了2.满了
                if(pos<num) 
                {
                  cout<<"新连接："<<sock<<" 已经被添加到了数组["<<pos<<"]的位置"<<endl;
                  fd_array[pos] = sock;
                }
                else 
                {
                  //服务器已经满载,无法处理请求
                  cout<<"服务器满载了"<<endl;
                  close(sock);
                }
              }
            }
            else 
            {
              //read,recv
                //普通的sock，读事件就绪了，可以进行读取了
              //本次一定能够读完吗？有粘包问题吗？不一定
              //仅仅测试
              cout<<"sock: "<<fd_array[i]<<"上面有普通读取"<<endl;
                        
              char buffer[1024] = {0};
              ssize_t s = recv(fd_array[i], buffer,sizeof(buffer)-1,0);
              if(s>0)
              {
                buffer[s] = '\0';
                cout<<"client#[ "<< fd_array[i]<<" ]# "<<buffer<<endl;
              }
              else if(s==0) 
              {
                //对端关闭了链接,
                cout<<"sock: "<<fd_array[i]<<"关闭了，clien退出了"<<endl;
                close(fd_array[i]);
                cout<<"已经在数组fd_array[ "<< i <<"]"<<" 中去掉了sock:  "<<fd_array[i]<<endl; 
                fd_array[i] =-1;
              }
              else 
              {
                  //读取失败
                close(fd_array[i]);
                cout<<"已经在数组fd_array[ "<< i <<"]"<<" 中去掉了sock:  "<<fd_array[i]<<endl; 
                fd_array[i] =-1;
              }
            }
          }
        }
        break;
    }
  }

  return 0;
}
